package cn.skyclass.net
{
	import flash.utils.Dictionary;
	import mx.controls.Alert;
		
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.soap.LoadEvent;
	import mx.rpc.soap.mxml.Operation;
	import mx.rpc.soap.mxml.WebService;

	/**
	 * 
	 * @author syg
	 * 
	 * 使用Dic存储WebService对象
	 * 
	 * 使用方法，
	 * 1. 定义自己的MyWsFactory类从WsFactory类继承, MyWsFactory一般只需定义一个单体模式
	 * 2. 应用启动时，调用MyFactory.getInstance().setContextUrl(url);
	 * 3. 如果WebService地址不同，可重载_getWsdl方法, 一般默认地址不需要重载。
	 */ 
	public class WsFactory
	{		
		private static var _serviceDic:Dictionary = new Dictionary();
		private static var _loadTagDic:Dictionary = new Dictionary();
		
		private var _contextUrl:String = "";
								
		public function setContextUrl(url:String):void{
			if(url.charAt(url.length - 1) != '/') {
				url += '/';
			}
			_contextUrl = url;
		}
		
		public function callService(serviceName:String, resultHandler:Function, errorMessage:String, 
			optionName:String, ... args):void{
			
			var service:WebService = _getWebService(serviceName);
			
			if(!_loadTagDic[serviceName]) {
				service.addEventListener(LoadEvent.LOAD, _onLoad);
				service.addEventListener(FaultEvent.FAULT, _onLoadFault);
				service.loadWSDL();
			} else {
				var option:Operation = service.getOperation(optionName) as Operation;
				option.arguments = args;
				option.addEventListener(ResultEvent.RESULT, _onResult);
				option.addEventListener(FaultEvent.FAULT, _onFault);
				option.send();								
			}
			
			function _onLoad(e:LoadEvent):void{
				_loadTagDic[serviceName] = true;
				service.removeEventListener(LoadEvent.LOAD, _onLoad);
				service.removeEventListener(FaultEvent.FAULT, _onLoadFault);
				
				callService(serviceName, resultHandler, errorMessage, optionName, args);
			}
			
			function _onLoadFault(e:FaultEvent):void{
				service.removeEventListener(LoadEvent.LOAD, _onLoad);
				service.removeEventListener(FaultEvent.FAULT, _onLoadFault);
				
				Alert.show(e.fault.toString(), "错误");
			}
			
			function _onResult(e:ResultEvent):void{
				_removeEventListener();				
				resultHandler(e);
			}
			
			function _onFault(e:FaultEvent):void {
				_removeEventListener();
				Alert.show(e.fault.toString(), "错误");
			}
			
			function _removeEventListener():void{
				option.removeEventListener(FaultEvent.FAULT, _onFault);
				option.removeEventListener(ResultEvent.RESULT, _onResult);				
			}
		}
		
		private function _getWebService(name:String):WebService {
			var ws:WebService = _serviceDic[name];
			if(ws == null) {
				ws = new WebService();
				ws.useProxy = false;
				ws.showBusyCursor = true;
				ws.wsdl = _getWsdl(name);
				
				_serviceDic[name] = ws;
				_loadTagDic[name] = false;
			}
			return ws;					
		}
				
		protected function _getWsdl(name:String):String{
			return _contextUrl + "services/" + name + "?wsdl";
		}
	}
}